/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lauglog.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Vector;
import javax.servlet.http.HttpSession;
import lauglog.bean.AccountBean;
import lauglog.bean.FriendsListBean;
import lauglog.bean.UserBean;
import lauglog.bean.UserEventsBean;
import lauglog.bean.UserPlansBean;
import lauglog.util.Event;
import lauglog.util.Friend;
import lauglog.util.MadePlan;

/**
 *
 * @author Kyle
 */
@WebServlet(name = "LoginServlet", urlPatterns = {"/LoginServlet"})
public class LoginServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    
    
    /*
     * Takes the action out of the request and uses it to call other methods
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String action = request.getParameter("action");
            if (action.equalsIgnoreCase("login")){
                request.setAttribute("username", request.getParameter("username"));
                request.setAttribute("password", request.getParameter("password"));
                checkCredentials(request,response);
            }
            else if (action.equalsIgnoreCase("logout"))
                logout(request,response);
            else if (action.equalsIgnoreCase("register")){
                register(request,response);
            }else if (action.equalsIgnoreCase("updateBeans")){
                updateBeans(request,response);
            }
            else;
        } finally {            
            out.close();
        }
    }

    /*
     * Used as a method to log in.  It checks the users inputed username and password
     * against what is stored in the database.  If a tuple is not returned, it is a 
     * bad login.
     */
    protected void checkCredentials(HttpServletRequest request, HttpServletResponse response){
        
        //Declare items for the connection.
        String url = "jdbc:mysql://localhost/lauglog";
        String dbUserName = "root";
        String dbPassword = "";
        String driver = "com.mysql.jdbc.Driver";
        
        Connection con = null;
        
        try{
            //Instantiate the connection
            Class.forName(driver).newInstance();
            con = DriverManager.getConnection(url, dbUserName, dbPassword);
            
            //Grab the user's username and password
            String username = (String)request.getAttribute("username");
            String password = (String)request.getAttribute("password");
            
            //Create and execute the query to pull the username and pass from the DB
            PreparedStatement loginStatement = con.prepareStatement("SELECT UserId FROM users WHERE UserName = ? AND Password = ?");
            loginStatement.setString(1, username);
            loginStatement.setString(2, password);
            ResultSet rs = loginStatement.executeQuery();
            
            
            //Did we find a tuple with those credentials?
            boolean success = rs.first();
            
            //Successful!
            if(success){
                int userID = rs.getInt("UserId");
                
                //Prepare and execute statement to see if user is a doctor too
                PreparedStatement isDoctor = con.prepareStatement("SELECT * FROM doctors WHERE UserId = ?");
                isDoctor.setInt(1, userID);
                ResultSet doc = isDoctor.executeQuery();
                boolean isDoc = doc.first();
                
                //Set the UserBean which is used throughout the application 
                //to verify and identify user
                UserBean user = new UserBean();
                user.setIsDoctor(isDoc);
                user.setUserID(userID);
                HttpSession session = request.getSession();
                session.setAttribute("user",user);
                
                //check to see if doctor or not
                if(isDoc){
                    //initiate doctor's dashboard
                    setupNotifications();
                    setupInbox();
                    setupAlerts(request);
                    setupUserPlans(request);
                    setupAlerts(request);
                    setupFriends(request);
                    setupAccount(request);
                    
                    response.sendRedirect("doctorDashboard.jsp");
                }else{
                 
                    //initiate standard user's dashboard
                    setupNotifications();
                    setupComments(request);
                    setupUserPlans(request);
                    setupTodaysEvents(request);
                    setupFriends(request);
                    setupAccount(request);
                    
                    response.sendRedirect("dashboard.jsp");
                }
            }else{
                //Failed to find that user/pass combination: Send to error
                response.sendRedirect("login.jsp?error=true");
            }
            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                con.close();
            }catch(Exception e){
                
            }
        }
        
    }
    
    public void updateBeans(HttpServletRequest request, HttpServletResponse response){
        
        setupNotifications();
        setupAccount(request);
        setupFriends(request);
        setupUserPlans(request);
        
        UserBean u = (UserBean)request.getSession().getAttribute("user");
        boolean isDoc = u.getIsDoctor();
        if(isDoc == true){
            setupInbox();
            setupAlerts(request);
        }else{
            setupComments(request);
            setupTodaysEvents(request);
        }
        
        try{
            response.sendRedirect((String)request.getSession().getAttribute("redirect"));
        }catch(Exception e){
            
        }
    }
    
    public void setupNotifications(HttpServletRequest request){
        
    }
    
    public void setupNotifications(){
        
    }
    public void setupInbox(){
        
    }
    
    public void setupComments(HttpServletRequest request){
        
        //Here we are setting a scheduler to repeadetly run two threads
        //which will run sql queries to update the user's comments
        //and friend requests
        /*
        ScheduledExecutorService updater = Executors.newSingleThreadScheduledExecutor();
        Runnable commentUpdateThread = new CommentUpdate(userID,request.getSession());
        
        //run the threads every one second starting now
        updater.scheduleAtFixedRate(commentUpdateThread, 0, 1, TimeUnit.SECONDS);*/
    }
    
    public void setupTodaysEvents(HttpServletRequest request){
         //Initiate variables for database queries
        String url = "jdbc:mysql://localhost/lauglog";
        String dbUserName = "root";
        String dbPassword = "";
        String driver = "com.mysql.jdbc.Driver";
        
        Connection con = null;
        try{
            
            //Make the connection
            Class.forName(driver).newInstance();
            con = DriverManager.getConnection(url, dbUserName, dbPassword);
            
            Calendar today = new GregorianCalendar();
            int dayOfWeek = today.get(Calendar.DAY_OF_WEEK)-1;
            String day = "";
            
            if(dayOfWeek == 0){
                day = "U";
            }else if(dayOfWeek == 1){
                day = "M";
            }else if(dayOfWeek == 2){
                day = "T";
            }else if(dayOfWeek == 3){
                day = "W";
            }else if(dayOfWeek == 4){
                day = "H";
            }else if(dayOfWeek == 5){
                day = "F";
            }else if(dayOfWeek == 6){
                day = "S";
            }
            
            System.out.print("Today : "+day);
            int userID = ((UserBean)request.getSession().getAttribute("user")).getUserID();
            
            PreparedStatement eventsStatement = con.prepareStatement("SELECT E.EventId, E.Name, E.Type FROM events E INNER JOIN (plans P INNER JOIN joined_plans JP ON P.PlanId = JP.PlanId AND JP.Completed = 0 AND JP.UserId = ?) ON P.PlanId = E.PlanId AND E.DayOfWeek LIKE '%"+day+"%'");
            eventsStatement.setInt(1, userID);
            ResultSet userEventsRs = eventsStatement.executeQuery();
            
            UserEventsBean userEvents = new UserEventsBean();
            Vector<Event> eventVector = new Vector();
            while(userEventsRs.next()){
                               
                Event e = new Event();
                e.setEventID(userEventsRs.getInt("EventId"));
                e.setEventName(userEventsRs.getString("Name"));
                e.setEventType(userEventsRs.getString("Type"));
                
                eventVector.add(e);
            }
            
            userEvents.setListEvents(eventVector);
            //Place the bean into the session
            HttpSession session = request.getSession();
            session.setAttribute("todaysEvents",userEvents);
            
            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                con.close();
            }catch(Exception e){
                
            }
        }
    }
    
    public void setupAlerts(HttpServletRequest request){
        
    }
    
    public void setupFriends(HttpServletRequest request){
        //Initiate variables for database queries
        String url = "jdbc:mysql://localhost/lauglog";
        String dbUserName = "root";
        String dbPassword = "";
        String driver = "com.mysql.jdbc.Driver";
        Vector<Friend> friends = new Vector();
        
        Connection con = null;
        try{
            
            //Make the connection
            Class.forName(driver).newInstance();
            con = DriverManager.getConnection(url, dbUserName, dbPassword);
            
            //
            int userID = ((UserBean)request.getSession().getAttribute("user")).getUserID();
            PreparedStatement userFriendsStatement = con.prepareStatement("SELECT FriendId, u.UserName, pi.Pic FROM (SELECT FriendId FROM friends WHERE YourId = ? UNION SELECT YourId FROM friends WHERE FriendId = ?) AS FriendId INNER JOIN users u ON u.UserId = FriendId INNER JOIN profile_information pi ON u.UserId = pi.UserId");
            userFriendsStatement.setInt(1, userID);
            userFriendsStatement.setInt(2, userID);
            ResultSet friendsRs = userFriendsStatement.executeQuery();
            
            while(friendsRs.next()){
                Friend f = new Friend();
                f.setFriendId(friendsRs.getInt("FriendId"));
                f.setFriendName(friendsRs.getString("UserName"));
                f.setProfilePicture("Pic");
                
                friends.add(f);
                System.out.println("\n\n\n"+friendsRs.getInt("FriendId")+"\n\n\n");
            }
            
            FriendsListBean friendsList = new FriendsListBean();
            friendsList.setFriendList(friends);
            
            HttpSession session = request.getSession();
            session.setAttribute("userFriends",friendsList);
            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                con.close();
            }catch(Exception e){
                
            }
        }
    }
    
    public void setupUserPlans(HttpServletRequest request){
        //Initiate variables for database queries
        String url = "jdbc:mysql://localhost/lauglog";
        String dbUserName = "root";
        String dbPassword = "";
        String driver = "com.mysql.jdbc.Driver";
        
        Connection con = null;
        try{
            
            //Make the connection
            Class.forName(driver).newInstance();
            con = DriverManager.getConnection(url, dbUserName, dbPassword);
            
            //
            int userID = ((UserBean)request.getSession().getAttribute("user")).getUserID();
            PreparedStatement userPlansStatement = con.prepareStatement("SELECT PlanName,PlanId FROM plans WHERE Creator = ?");
            userPlansStatement.setInt(1, userID);
            ResultSet userPlansRs = userPlansStatement.executeQuery();
            
            UserPlansBean userPlansBean = new UserPlansBean();
            Vector<MadePlan> planVector = new Vector();
            while(userPlansRs.next()){
                               
                MadePlan m = new MadePlan();
                m.setPlanID(userPlansRs.getInt("PlanId"));
                m.setPlanName(userPlansRs.getString("PlanName"));
                m.setJoined(false);
                
                planVector.add(m);
                
            }
            
            PreparedStatement userJoinedPlansStatement = con.prepareStatement("SELECT PlanId FROM joined_plans WHERE UserId = ?");
            userJoinedPlansStatement.setInt(1,userID);
            ResultSet userJoinedPlansRs = userJoinedPlansStatement.executeQuery();
            
            while(userJoinedPlansRs.next()){
                int thisPlanId = userJoinedPlansRs.getInt("PlanId");
                
                for(int i = 0; i < planVector.size(); i++){
                    if(planVector.get(i).getPlanID() == thisPlanId){
                        planVector.get(i).setJoined(true);
                    }
                }
            }
            userPlansBean.setListPlans(planVector);
            //Place the bean into the session
            HttpSession session = request.getSession();
            session.setAttribute("userPlans",userPlansBean);
            
            
            //Get plans joined from other users
            UserPlansBean searchedPlansBean = new UserPlansBean();
            Vector searchedPlanVector = new Vector();
            
            PreparedStatement userJoinedOtherPlan = con.prepareStatement("SELECT jp.PlanId, p.PlanName FROM joined_plans jp INNER JOIN plans p ON jp.PlanId = p.PlanId AND p.Creator <> ? AND jp.UserId = ?");
            userJoinedOtherPlan.setInt(1, userID);
            userJoinedOtherPlan.setInt(2, userID);
            ResultSet userJoinedOtherPlanRs = userJoinedOtherPlan.executeQuery();
            
            while(userJoinedOtherPlanRs.next()){
                MadePlan m = new MadePlan();
                m.setJoined(true);
                m.setPlanID(userJoinedOtherPlanRs.getInt("PlanId"));
                m.setPlanName(userJoinedOtherPlanRs.getString("PlanName"));
                searchedPlanVector.add(m);
            }
            
            searchedPlansBean.setListPlans(searchedPlanVector);
            session.setAttribute("searchedPlans", searchedPlansBean);
            
            for(int i = 0; i < planVector.size(); i++){
                if(planVector.get(i).isJoined() == true){
                    searchedPlanVector.add(planVector.get(i));
                }
            }
            
            UserPlansBean joinedPlansBean = new UserPlansBean();
            joinedPlansBean.setListPlans(searchedPlanVector);
            session.setAttribute("joinedPlans", joinedPlansBean);
            
            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                con.close();
            }catch(Exception e){
                
            }
        }
    }
    
    public void setupAccount(HttpServletRequest request){
        //Initiate variables for database queries
        String url = "jdbc:mysql://localhost/lauglog";
        String dbUserName = "root";
        String dbPassword = "";
        String driver = "com.mysql.jdbc.Driver";
        
        Connection con = null;
        try{
            int userID = ((UserBean)request.getSession().getAttribute("user")).getUserID();
            //Make the connection
            Class.forName(driver).newInstance();
            con = DriverManager.getConnection(url, dbUserName, dbPassword);
            
            //Prepare and execute the statement for grabbing account information
            PreparedStatement accountInformation = con.prepareStatement("SELECT * FROM profile_information WHERE UserId = ?");
            accountInformation.setInt(1, userID);
            ResultSet accountInfo = accountInformation.executeQuery();
            accountInfo.first();
            
            //Prepare and execute the statement for grabbing user information
            PreparedStatement userInformation = con.prepareStatement("SELECT * FROM users WHERE UserId = ?");
            userInformation.setInt(1, userID);
            ResultSet userInfo = userInformation.executeQuery();
            userInfo.first();
            
            //Get profile privacy setting
            PreparedStatement profilePrivacyStatement = con.prepareStatement("SELECT Setting FROM privacy_information WHERE UserId=?");
            profilePrivacyStatement.setInt(1, userID);
            ResultSet profilePrivacyRs = profilePrivacyStatement.executeQuery();
            profilePrivacyRs.first();
            
            //Place information into a new Account Bean
            AccountBean userAccount = new AccountBean();
            userAccount.setFirstName(userInfo.getString("FirstName"));
            userAccount.setLastName(userInfo.getString("LastName"));
            userAccount.setCity(accountInfo.getString("City"));
            userAccount.setState(accountInfo.getString("State"));
            userAccount.setCountry(accountInfo.getString("Country"));
            userAccount.setEducation(accountInfo.getString("Education"));
            userAccount.setHeight(accountInfo.getFloat("Height"));
            userAccount.setWeight(accountInfo.getFloat("Weight"));
            userAccount.setProfilePic(accountInfo.getString("Pic"));
            userAccount.setSex(accountInfo.getString("Sex"));
            userAccount.setEmail(userInfo.getString("Email"));
            userAccount.setProfilePrivacy(profilePrivacyRs.getInt("Setting"));
            
            //Place the bean into the session
            HttpSession session = request.getSession();
            session.setAttribute("userAccount",userAccount);
            
            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                con.close();
            }catch(Exception e){
                
            }
        }
    }
    
    public void logout(HttpServletRequest request, HttpServletResponse response){
        
        //get the session, invalidate it and give the user a new one
        HttpSession session = request.getSession();
        session.invalidate();
        request.getSession(true);
        
        //redirect to the login page
        try{
            response.sendRedirect("login.jsp");
        }catch(Exception e){
            
        }
    }
    
    public void register(HttpServletRequest request, HttpServletResponse response){
        
        //Initiate variables for database queries
        String url = "jdbc:mysql://localhost/lauglog";
        String dbUserName = "root";
        String dbPassword = "";
        String driver = "com.mysql.jdbc.Driver";
        
        Connection con = null;
        try{
            
            //Make the connection
            Class.forName(driver).newInstance();
            con = DriverManager.getConnection(url, dbUserName, dbPassword);
            
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            String email = request.getParameter("email");
            String firstName = request.getParameter("firstName");
            String lastName = request.getParameter("lastName");
            
            //Execute a statement to grab the registering user's desired user and email
            PreparedStatement loginStatement = con.prepareStatement("SELECT UserName, Email FROM users WHERE UserName = ? OR Email = ?");
            loginStatement.setString(1, username);
            loginStatement.setString(2, email);
            ResultSet rs = loginStatement.executeQuery();
            
            //Is it already taken?
            boolean alreadyTaken = rs.first();
            
            if(!alreadyTaken){
                //If it's not taken, make the account
                PreparedStatement newUser = con.prepareStatement("INSERT INTO users (FirstName,LastName,Email,UserName,Password) VALUES (?,?,?,?,?)");
                newUser.setString(1,firstName);
                newUser.setString(2,lastName);
                newUser.setString(3,email);
                newUser.setString(4,username);
                newUser.setString(5,password);
                int success = newUser.executeUpdate();
                
                //Grab the user's new UserID to give them default tuples in other tables
                PreparedStatement userInfo = con.prepareStatement("SELECT UserId FROM users WHERE UserName = ? AND Password = ?");
                userInfo.setString(1, username);
                userInfo.setString(2, password);
                ResultSet userId = userInfo.executeQuery();
                userId.first();
                int userID = userId.getInt("UserId");
                
                //Grant them a tuple in profile information
                PreparedStatement profInfo = con.prepareStatement("INSERT INTO profile_information (UserId) VALUES (?)");
                profInfo.setInt(1, userID);
                success = profInfo.executeUpdate();
                
                //Grant them default tuples in the privacy information table
                PreparedStatement privInfo = con.prepareStatement("INSERT INTO privacy_information (UserId, Setting) VALUES (?,?)");
                privInfo.setInt(1, userID);
                privInfo.setInt(2, 1);
                privInfo.executeUpdate();
                
                String DEA = request.getParameter("dea");
                
                request.setAttribute("username", username);
                request.setAttribute("password", password);
                        
                if(DEA == null || DEA.equals("")){
                    //Not a doctor
                    //response.sendRedirect("dashboard.jsp");
                }else{
                    //Doctor!
                    
                    //Code to authenticate DEA would go here
                    // .....
                    // .....
                    
                    PreparedStatement doctor = con.prepareStatement("INSERT INTO doctors (UserId, DEA) VALUES (?,?)");
                    doctor.setInt(1, userID);
                    doctor.setString(2, DEA);
                    doctor.executeUpdate();
                    
                    //response.sendRedirect("doctorDashboard.jsp");
                }
                
                checkCredentials(request,response);
                
                
            }else{
                response.sendRedirect("login.jsp?error=true");
            }
            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                con.close();
            }catch(Exception e){
                
            }
        }
    }
    
    
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
